Nginx 配置速查
日常配置的高频指令和可直接抄的片段,随用随查。环境口径 Ubuntu 22.04 + nginx 1.24,改完一律 nginx -t && nginx -s reload。
常用指令速查
| 指令 | 作用 | 示例 |
|---|---|---|
worker_processes | worker 进程数,按 CPU 核数 | worker_processes auto; |
worker_rlimit_nofile | worker 可打开的 fd 上限 | worker_rlimit_nofile 65535; |
worker_connections | 单 worker 最大连接数(events 层) | worker_connections 10240; |
use | 事件模型,Linux 默认 epoll | use epoll; |
multi_accept | 一次事件循环接多个新连接 | multi_accept on; |
include | 引入其他配置文件 | include /etc/nginx/conf.d/*.conf; |
listen | 监听地址与端口 | listen 443 ssl http2; |
server_name | 虚拟主机域名,空格分隔多个 | server_name example.com www.example.com; |
root | 站点根目录,拼完整 URI | root /var/www/html; |
alias | 用指定路径替换 location 前缀 | alias /data/files/; |
index | 目录默认文件 | index index.html index.htm; |
try_files | 依次尝试文件,末位兜底 | try_files $uri $uri/ /index.html; |
location | URI 匹配规则 | location ^~ /static/ { ... } |
proxy_pass | 转发到上游,尾斜杠决定是否改写 URI | proxy_pass http://backend/; |
proxy_set_header | 设置转发请求头 | proxy_set_header Host $host; |
proxy_http_version | 转发使用的 HTTP 版本 | proxy_http_version 1.1; |
proxy_connect_timeout | 连接上游超时 | proxy_connect_timeout 5s; |
proxy_read_timeout | 读上游响应超时(504 的来源) | proxy_read_timeout 60s; |
proxy_send_timeout | 向上游发送超时 | proxy_send_timeout 60s; |
proxy_buffering | 是否缓冲上游响应 | proxy_buffering off; |
proxy_cache_path | 定义缓存目录与 zone(http 层) | proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=c:100m; |
proxy_cache | 引用缓存 zone | proxy_cache c; |
client_max_body_size | 请求体大小上限(413 的来源) | client_max_body_size 20m; |
client_header_timeout | 读请求头超时 | client_header_timeout 15s; |
keepalive_timeout | 客户端长连接空闲超时 | keepalive_timeout 65s; |
keepalive_requests | 单连接最多复用次数 | keepalive_requests 1000; |
sendfile | 零拷贝发送静态文件 | sendfile on; |
tcp_nopush | 攒满包再发,配合 sendfile | tcp_nopush on; |
tcp_nodelay | 小包立即发,降低延迟 | tcp_nodelay on; |
gzip | 开启压缩 | gzip on; |
gzip_types | 哪些 MIME 类型压缩 | gzip_types text/css application/json; |
gzip_comp_level | 压缩级别 1-9 | gzip_comp_level 5; |
expires | 浏览器缓存时长 | expires 30d; |
add_header | 加响应头 | add_header Cache-Control "no-store" always; |
rewrite | URI 改写 | rewrite ^/old/(.*)$ /new/$1 permanent; |
return | 直接返回状态码或跳转 | return 301 https://$host$request_uri; |
limit_req_zone | 限流 zone(http 层) | limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s; |
limit_req | 在 location 应用限流 | limit_req zone=api burst=20 nodelay; |
stub_status | 状态页 | stub_status; |
access_log | 访问日志 | access_log /var/log/nginx/access.log main; |
error_log | 错误日志与级别 | error_log /var/log/nginx/error.log warn; |
server_tokens | 是否显示版本号 | server_tokens off; |
resolver | DNS 服务器,proxy_pass 用域名时必需 | resolver 223.5.5.5 valid=30s; |
location 匹配规则
| 写法 | 类型 | 优先级 | 说明 |
|---|---|---|---|
= /path | 精确匹配 | 1(最高) | 命中即返回,不再匹配 |
^~ /prefix/ | 前缀匹配 | 2 | 命中后跳过正则检查 |
~ pattern | 正则,区分大小写 | 3 | 按配置出现顺序,先匹配者胜 |
~* pattern | 正则,不区分大小写 | 4 | 同上 |
/prefix/ | 普通前缀 | 5(最低) | 取最长前缀 |
常用组合:
server {
listen 80;
server_name example.com;
# 健康检查:最短链路
location = /health {
access_log off;
return 200 "ok\n";
}
# 静态目录:^~ 防止被下面的正则抢走
location ^~ /static/ {
root /var/www;
expires 30d;
}
# 图片:正则
location ~* \.(jpg|jpeg|png|webp|svg)$ {
root /var/www/images;
expires 7d;
}
# API:前缀转发
location /api/ {
proxy_pass http://app_backend/;
}
# 兜底
location / {
root /var/www/html;
try_files $uri $uri/ /index.html;
}
}
反向代理片段
upstream app_backend {
server 10.0.0.11:8080 weight=5 max_fails=3 fail_timeout=10s;
server 10.0.0.12:8080 weight=1;
keepalive 64;
}
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://app_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Request-ID $request_id;
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# SSE / WebSocket / 流式输出:关缓冲、拉长超时
location /stream/ {
proxy_pass http://app_backend;
proxy_buffering off;
proxy_read_timeout 3600s;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
HTTPS 片段
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/certs/example.com.pem;
ssl_certificate_key /etc/nginx/certs/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
add_header Strict-Transport-Security "max-age=31536000" always;
location / {
proxy_pass http://app_backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
gzip 与缓存片段
# gzip 放 http 层
gzip on;
gzip_vary on;
gzip_comp_level 5;
gzip_min_length 1k;
gzip_proxied any;
gzip_types
text/plain
text/css
text/xml
application/javascript
application/json
application/xml
image/svg+xml;
# 服务端缓存
proxy_cache_path /var/cache/nginx/data
levels=1:2
keys_zone=api_cache:100m
max_size=10g
inactive=60m
use_temp_path=off;
server {
location /api/public/ {
proxy_pass http://app_backend;
proxy_cache api_cache;
proxy_cache_key "$scheme$host$request_uri";
proxy_cache_valid 200 302 10m;
proxy_cache_use_stale error timeout http_502 http_503;
proxy_cache_lock on;
add_header X-Cache-Status $upstream_cache_status always;
}
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
日志格式片段
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'rt=$request_time urt=$upstream_response_time '
'uht=$upstream_header_time upstream=$upstream_addr '
'request_id=$request_id';
校验与信号
| 操作 | 命令 | 说明 |
|---|---|---|
| 语法检查 | nginx -t | 只读检查,不生效 |
| 打印生效配置 | nginx -T | 展开所有 include,排查「改了不生效」 |
| 平滑重载 | nginx -s reload | 新 worker 接新连接,老 worker 处理完退出 |
| 重开日志 | nginx -s reopen | 等价 kill -USR1,配合 logrotate |
| 优雅停机 | nginx -s quit | 处理完存量请求再退 |
| 快速停机 | nginx -s stop | 立即退出 |
| 平滑升级 | kill -USR2 $(cat /var/run/nginx.pid) | 起新 master |
| 关闭老 worker | kill -WINCH $(cat /var/run/nginx.pid.oldbin) | 升级流程第 6 步 |
排障命令
| 目的 | 命令 |
|---|---|
| 看实时访问日志 | tail -f /var/log/nginx/access.log |
| 看错误 | tail -n 100 /var/log/nginx/error.log |
| 找慢请求(按 rt 排序) | grep -o 'rt=[0-9.]*' access.log | cut -d= -f2 | sort -n | tail |
| 统计状态码分布 | awk '{print $9}' access.log | sort | uniq -c | sort -rn |
| 端口监听 | ss -lntp | grep nginx |
| 进程与 worker | ps -ef | grep nginx |
| 连接状态 | ss -s |
| 压力测试 | wrk -t4 -c400 -d60s --latency http://127.0.0.1/ |
| 测后端连通 | curl -sv --connect-timeout 3 http://10.0.0.11:8080/health |
| 状态页 | curl http://127.0.0.1:8081/stub_status |